package org.sherlock.plugins.revealers;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.sherlock.commons.model.RemoteFile;
import org.sherlock.commons.plugins.RevealerException;
import org.sherlock.commons.plugins.URLRevealer;

/**
 *
 * @author Sherlock Downloader
 */
public class Revealer extends URLRevealer {

    @Override
    public ArrayList<RemoteFile> getURLs(URL url) throws RevealerException {
        ArrayList<RemoteFile> files = new ArrayList<RemoteFile>();
        try {
            String id = getId(url.toString());
            //System.out.println("ID = " + id);
            if (id == null) {
                return files;
            }
            URL xmlUrl = new URL(generateVideoXmlUrl(id));
            //System.out.println("xmlUrl = " + xmlUrl);
            String xmlContent = getContent(xmlUrl.openStream(), Charset.defaultCharset());
            if (xmlHasFileAddress(xmlContent)) {
				files.add(new RemoteFile(new URI(lookForFileTagInXml(xmlContent)), true));
            } else if (xmlHasAnAssetXmlAddress(xmlContent)) {
                files.add(new RemoteFile(new URI(lookForFileWithAnAssetDataVideoXmlAddress(xmlContent)), true));
            }
        } catch (MalformedURLException ex) {
            Logger.getLogger(Revealer.class.getName()).log(Level.SEVERE, null, ex);

        } catch (IOException ex) {
            Logger.getLogger(Revealer.class.getName()).log(Level.SEVERE, null, ex);
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return files;
    }

    private String lookForFileTagInXml(String source) {
        return getFileFromXmlAddress(source);
    }

    private String getFileFromXmlAddress(String source) {
        if (!xmlHasFileAddress(source)) {
            throw new IllegalArgumentException();
        }
        return source.split("<file>")[1].split("</file>")[0];
    }

    private String lookForFileWithAnAssetDataVideoXmlAddress(String source) throws MalformedURLException, IOException {
        String assetRelativeLocation = getAssetXmlDefaultLocation(getContent(new URL(generateAssetDataVideoIdXmlUrl(getAssetId(source))).openStream(), Charset.defaultCharset()));
        if (assetRelativeLocation.contains("/flv/")) {
            return generateAssetDownloadLocation("flv", assetRelativeLocation);
        }
        if (assetRelativeLocation.contains("/mp4/")) {
            return generateAssetDownloadLocation("mp4", assetRelativeLocation);
        }
        throw new IOException();
    }

    private String generateAssetDownloadLocation(String format, String relativeLocation) {
        return "http://www.rtve.es/resources/TE_NGVA/" + format + "/" + relativeLocation.split("/" + format + "/")[1];
    }

    private String getAssetXmlDefaultLocation(String source) {
        return source.split("defaultLocation=\"")[1].split("\"")[0];
    }

    private String generateAssetDataVideoIdXmlUrl(String id) {
        return "http://www.rtve.es/scd/CONTENTS/ASSET_DATA_VIDEO/" + id.charAt(5) + "/" + id.charAt(4) + "/" + id.charAt(3) + "/" + id.charAt(2) + "/ASSET_DATA_VIDEO-" + id + ".xml";
    }

    private String getAssetId(String source) {
        return source.split("assetDataId::")[1].substring(0, 6);
    }

    private boolean xmlHasFileAddress(String source) {
        return source.contains("<file>") && source.contains("</file>");
    }

    private boolean xmlHasAnAssetXmlAddress(String source) {
        return source.contains("<file/>") && source.contains("assetDataId::");
    }

    private String getIdOfSHTMLPages(String link) {
        try {
            String content = getContent(new URL(link).openStream(), Charset.defaultCharset());
            return content.split("RTVEPlayerVideo\\.swf\\?assetID=")[1].split("_")[0];
        } catch (IOException ex) {
            return null;
        }
    }

    private String getId(String link) {
        if (link.endsWith(".shtml")) {
            getIdOfSHTMLPages(link);
        }
        String[] aux = link.split("/");
        String id = aux[aux.length - 1].split("\\.")[0];
        for (int i = 0; i < id.length(); i++) {
            if (!Character.isDigit(id.charAt(i))) {
                return null;
            }
        }
        return id;
    }

    private String generateVideoXmlUrl(String id) {
        return "http://www.rtve.es/swf/data/es/videos/video/" + id.charAt(id.length() - 1) + "/" + id.charAt(id.length() - 2) + "/" + id.charAt(id.length() - 3) + "/" + id.charAt(id.length() - 4) + "/" + id + ".xml";
    }
}